package com.uraurora.crescent.function;

import java.util.Objects;

@FunctionalInterface
public interface Func9<T1, T2, T3, T4, T5, T6, T7, T8, T9, RT> {

    RT on(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9);

    default <V> Func9<T1, T2, T3, T4, T5, T6, T7, T8, T9, V> after(Func1<? super RT, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9) ->
                after.on(on(t1, t2, t3, t4, t5, t6, t7, t8, t9));
    }

    default Func8<T2, T3, T4, T5, T6, T7, T8, T9, RT> curry1(T1 t1){
        return (t2, t3, t4, t5, t6, t7, t8, t9) -> on(t1, t2, t3, t4, t5, t6, t7, t8, t9);
    }

    default Func8<T1, T3, T4, T5, T6, T7, T8, T9, RT> curry2(T2 t2){
        return (t1, t3, t4, t5, t6, t7, t8, t9) -> on(t1, t2, t3, t4, t5, t6, t7, t8, t9);
    }

    default Func8<T1, T2, T4, T5, T6, T7, T8, T9, RT> curry3(T3 t3){
        return (t1, t2, t4, t5, t6, t7, t8, t9) -> on(t1, t2, t3, t4, t5, t6, t7, t8, t9);
    }

    default Func8<T1, T2, T3, T5, T6, T7, T8, T9, RT> curry4(T4 t4){
        return (t1, t2, t3, t5, t6, t7, t8, t9) -> on(t1, t2, t3, t4, t5, t6, t7, t8, t9);
    }

    default Func8<T1, T2, T3, T4, T6, T7, T8, T9, RT> curry5(T5 t5){
        return (t1, t2, t3, t4, t6, t7, t8, t9) -> on(t1, t2, t3, t4, t5, t6, t7, t8, t9);
    }

    default Func8<T1, T2, T3, T4, T5, T7, T8, T9, RT> curry6(T6 t6){
        return (t1, t2, t3, t4, t5, t7, t8, t9) -> on(t1, t2, t3, t4, t5, t6, t7, t8, t9);
    }

    default Func8<T1, T2, T3, T4, T5, T6, T8, T9, RT> curry7(T7 t7){
        return (t1, t2, t3, t4, t5, t6, t8, t9) -> on(t1, t2, t3, t4, t5, t6, t7, t8, t9);
    }

    default Func8<T1, T2, T3, T4, T5, T6, T7, T9, RT> curry8(T8 t8){
        return (t1, t2, t3, t4, t5, t6, t7, t9) -> on(t1, t2, t3, t4, t5, t6, t7, t8, t9);
    }

    default Func8<T1, T2, T3, T4, T5, T6, T7, T8, RT> curry9(T9 t9){
        return (t1, t2, t3, t4, t5, t6, t7, t8) -> on(t1, t2, t3, t4, t5, t6, t7, t8, t9);
    }

}